package tools.neoBio;

import java.io.FileReader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;

import tools.fasta.FastaSeq;

import neobio.alignment.NeedlemanWunsch;
import neobio.alignment.PairwiseAlignment;
import neobio.alignment.ScoringMatrix;
import neuro.uu.se.utils.WorkStrategy;

public class alignNeedle implements WorkStrategy {

	ArrayList<FastaSeq> seq2;
	String Matrix;
	public alignNeedle(ArrayList<FastaSeq>seq2,String Matrix){
		this.seq2=seq2;
		this.Matrix=Matrix;
	}
	@Override
	public Object perform(Object object) throws Exception {
		PairwiseAlignment pa;
		String s1,s2,tag;
		int pos1,pos2;
		NeedlemanWunsch nw= new NeedlemanWunsch();
		nw.setScoringScheme(new ScoringMatrix(new FileReader(Matrix)));
		HashMap<String, HashMap<Integer, Integer>> res1= new HashMap<String, HashMap<Integer,Integer>>();
		HashMap<String, HashMap<Integer, Integer>> res2= new HashMap<String, HashMap<Integer,Integer>>();
		FastaSeq one= (FastaSeq)object;
		
		for (FastaSeq two : seq2) {
			nw.loadSequences(new StringReader(one.getSeq()), new StringReader(two.getSeq()));
			pa=nw.getPairwiseAlignment();
			nw.unloadSequences();
			// analyze the alignment pa
			s1=pa.getGappedSequence1();
			s2=pa.getGappedSequence2();
			tag=pa.getScoreTagLine();
			pos1=-1; //first position is 0
			pos2=-1;
			for(int i=0;i<tag.length();i++){
				if(s1.charAt(i)!=' '){
					pos1++;
				}
				if(s2.charAt(i)!=' '){
					pos2++;
				}
				if(tag.charAt(i)!=' '&&tag.charAt(i)!='+'){
					//res1
					if(!res1.containsKey(one.getQname())){
						res1.put(one.getQname(), new HashMap<Integer, Integer>());
					}
					if(res1.get(one.getQname()).containsKey(pos1)){
						res1.get(one.getQname()).put(pos1, res1.get(one.getQname()).get(pos1)+1);
					}else{
						res1.get(one.getQname()).put(pos1, 1);
					}
					//res2
					if(!res2.containsKey(two.getQname())){
						res2.put(two.getQname(), new HashMap<Integer, Integer>());
					}
					if(res2.get(two.getQname()).containsKey(pos2)){
						res2.get(two.getQname()).put(pos2, res2.get(two.getQname()).get(pos2)+1);
					}else{
						res2.get(two.getQname()).put(pos2, 1);
					}
				}
			}
		}
		ArrayList<HashMap<String, HashMap<Integer, Integer>>> back= new ArrayList<HashMap<String,HashMap<Integer,Integer>>>();
		back.add(res1);
		back.add(res2);
		return back;
	}

}
